<?php
class BaseModelMySQLi extends BaseModelDBO {
    /**
     * The class constructor.
     *
     * @param string $host name of database host
     * @param string $user name of database user
     * @param string $passwd name of database password
     * @param string $dbname name of database name
     * @param unsigned integer $port name of database port
    */
    public function __construct($host,$user,$passwd,$dbname,$port) {
        $this->_host = $host;
        $this->_user = $user;
        $this->_passwd = $passwd;
        $this->_dbName = $dbname;
        $this->_port = $port;
       
        $this->_setUniqueKey();
        $_uniqueDBKey = $this->_getUniqueKey();

        if( NULL === self::$links[$_uniqueDBKey] ) {
            //echo "invocked";    
            $this->_link = @new mysqli($this->_host,$this->_user,$this->_passwd,$this->_dbName,$this->_port);

            self::$links[$_uniqueDBKey] = $this->_link ? $this->_link : NULL;
        }
        $this->_link = self::$links[$_uniqueDBKey];
    }
    /**
     * Execute an SQL query.
     *
     * @param string $query name of sql query 
     * @return MYSQLI_RESULT object 
    */
    public function runQuery($query) {
        if( !$this->checkLink() ) {
            return false;
        }

        $_result = $this->_link->query($query);

        return $_result;
    }
	 /**
     * Execute SQLs query.
     *
     * @param string $query name of sql query 
     * @return MYSQLI_RESULT object 
    */
    public function runMultiQuery($query) {
        if( !$this->checkLink() ) {
            return false;
        }

        $_result = $this->_link->multi_query($query);

        return $_result;
    }
    /**
     * Get MYSQLI_RESULT object attributes by a query SQL.
     *
     * @param string $query name of sql query
     * @param reference array $attrs name of MYSQLI_RESULT object attributes
     * @return bool 
    */
    public function getAttributes($query,&$attrs=array()) {
        if( !$this->checkLink() ) {
            return false;    
        }

		$_msg = false;
        if( ( $_result = self::runQuery($query) ) ) {
            if( ( $_num = $_result->num_rows ) > 0 ) {
                $_i = 0;
                while( $_row = $_result->fetch_array(MYSQLI_ASSOC) ) {
                    foreach( $_row as $_key => $_value ) {
                        $attrs[$_i][$_key] = $_value;
                    }
                    $_i++;
                }
                $_msg = QUERY_SUCC;
            }
			else {
				$_msg = NO_FETCH_RESULT;
			}
        }
		else {
        	$_msg = QUERY_ERR;
		} 
		if(QUERY_SUCC == $_msg || NO_FETCH_RESULT == $_msg){
			return true;
		}
		else{
			return false;
		}
    }
    /**
     * Get the execute sql query an attribute.
     *
     * @param string $query name of sql query
	 * @param string $val name of sql result
     * @return bool 
    */
    public function getOneAttribute($query,&$val=NULL) {
        if( !$this->checkLink() ) {
            return false;
        }
		
		$_msg = false;
		$val = NULL;
        if( $_result = self::runQuery($query) ) {
            if( ( $_num = $_result->num_rows ) > 0 ) {
                $_row = $_result->fetch_array(MYSQLI_NUM);
                $val = $_row[0];
				$_msg = QUERY_SUCC;
            }
            else {
                $_msg = NO_FETCH_RESULT;
            }
        }
		else{
        	$_msg = QUERY_ERR;
		}
		if(QUERY_SUCC == $_msg || NO_FETCH_RESULT == $_msg){
			return true;
		}
		else{
			return false;
		}
    }
    /**
     * Get the execute sql query affected new thread id.
     *
     * @return integer, -1:meaning error mysqli link,otherwise will be ok. 
    */
    public function getInsertId() {
        if( !$this->checkLink() ) {
            return -1;
        }
        return $this->_link->insert_id;
    }
    /**
     * Get the execute sql query affected row numbers.
     *
     * @return integer,greater than 0 will be ok
    */
    public function getAffectedRows() {
        if( !$this->checkLink() ) {
            return false;
        }
        return $this->_link->affected_rows;
    }
    /**
     * Set the mysqli link to close.
     *
     * @return boolean 
    */
    public function close() {
        if( !$this->_checkLink() ) {
            return false;
        }
        unset(self::$links[$this->_getUniqueKey()]);
        return $this->_link->close();
    }
    /**
     * Get the execute sql query error message.
     *
     * @return string 
    */
    public function errorInfo() {
        return $this->_link->error;
    }
    /**
     * Get the execute sql query error number.
     *
     * @return integer,zero means no error occurred 
    */
    public function errorCode() {
        return $this->_link->errno;
    }
	/**
	 * Get real escaping string
	 *
	 * @return string
	*/
	public function escape($str) {
		return $this->_link->real_escape_string($str);
	}
    /**
     * Check the mysqli link isn't ok.
     *
     * @return boolean 
    */
    public function checkLink() {
       return (false == $this->_link) ? false : true;
    }
}
?>